package com.zb.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zb.constant.UserConstant;
import com.zb.entity.ZjAdmServicePage;
import com.zb.entity.ZjServicePage;
import com.zb.entity.ZjServicePageIcon;
import com.zb.entity.ZjWorkModule;
import com.zb.exception.ZbException;
import com.zb.extend.ServicePageExtend;
import com.zb.result.PageUtil;
import com.zb.secure.BCryptUtil;
import com.zb.service.*;
import com.zb.system.service.ConServicePageService;
import com.zb.utils.TemplateReplaceUtil;
import com.zb.utils.ZbManager;
import com.zb.vo.*;
import com.zb.yaml.EnDeSecret;
import com.zb.yaml.MobilePath;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * @Author WEN
 * @Date 2023/10/31 0031
 **/
@Service
public class ConServicePageServiceImpl implements ConServicePageService {
    @Resource
    private ZjAdmServicePageService admServicePageService;
    @Resource
    private ZjServicePageService servicePageService;
    @Resource
    private ZjWorkModuleService workModuleService;
    @Resource
    private ZjServicePageIconService servicePageIconService;

    // 同步服务页面
    @Override
    @Transactional
    public void syncServicePage(Long custAccId) {
        QueryWrapper<ZjAdmServicePage> admServicePageQueryWrapper = new QueryWrapper<>();
        admServicePageQueryWrapper.eq("is_disabled", false);
        List<ZjAdmServicePage> admServicePageList = admServicePageService.list(admServicePageQueryWrapper);
        List<ZjServicePage> adds = new ArrayList<>();
        List<ZjServicePage> updates = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(admServicePageList)) {
            List<Long> admServicePageIds = admServicePageList.stream().map(ZjAdmServicePage::getId).toList();
            QueryWrapper<ZjServicePage> wrapper = new QueryWrapper<>();
            wrapper.eq("cust_acc_id", custAccId).in("adm_service_page_id", admServicePageIds);
            List<ZjServicePage> pageList = servicePageService.list(wrapper);

            ZjServicePage page = null;
            for (ZjAdmServicePage admPage : admServicePageList) {
                page = pageList.stream().filter(f -> Objects.equals(f.getAdmServicePageId(), admPage.getId())).findFirst().orElse(null);
                if (null != page) {
                    page.setType(admPage.getType());
                    updates.add(page);
                    continue;
                }
                page = new ZjServicePage();
                page.setId(IdWorker.getId());
                page.setCustAccId(custAccId);
                page.setAdmServicePageId(admPage.getId());
                page.setType(admPage.getType());
                page.setModuleId(0L);
                page.setPageTitle(admPage.getPageTitle());
                page.setQrStyleType(1);
                page.setQrBackgroundColor("");
                page.setQrTextColor("");
                page.setQrTitle(admPage.getName());
                page.setQrProgramme("");
                page.setDisabled(false);
                adds.add(page);
            }
        }
        QueryWrapper<ZjWorkModule> moduleQueryWrapper = new QueryWrapper<>();
        moduleQueryWrapper.select("id");
        moduleQueryWrapper.eq("cust_acc_id", custAccId).eq("is_disabled", false);
        int count = workModuleService.count(moduleQueryWrapper);
        getModuleServicePage(custAccId, 1L, count, adds);

        if (CollectionUtil.isNotEmpty(adds)) servicePageService.saveBatch(adds);
        if (CollectionUtil.isNotEmpty(updates)) servicePageService.updateBatchById(updates);
    }

    private void getModuleServicePage(Long custAccId, Long pageNum, int totalCount, List<ZjServicePage> adds) {
        Long limit = 50L;
        QueryWrapper<ZjWorkModule> moduleQueryWrapper = new QueryWrapper<>();
        moduleQueryWrapper.select("id", "name");
        moduleQueryWrapper.eq("cust_acc_id", custAccId).eq("is_disabled", false);
        Page<ZjWorkModule> page = workModuleService.page(new Page<>((pageNum -1) * limit, limit), moduleQueryWrapper);
        List<ZjWorkModule> moduleList = page.getRecords();
        if (CollectionUtil.isEmpty(moduleList)) {
            return;
        }
        QueryWrapper<ZjServicePage> wrapper = new QueryWrapper<>();
        wrapper.eq("cust_acc_id", custAccId).in("module_id", moduleList.stream().map(ZjWorkModule::getId).toList());
        List<ZjServicePage> pageList = servicePageService.list(wrapper);

        ZjServicePage servicePage = null;
        for (ZjWorkModule module : moduleList) {
            if (pageList.stream().noneMatch(f -> Objects.equals(f.getModuleId(), module.getId()))) {
                servicePage = new ZjServicePage();
                servicePage.setId(IdWorker.getId());
                servicePage.setCustAccId(custAccId);
                servicePage.setAdmServicePageId(0L);
                servicePage.setType(1);
                servicePage.setModuleId(module.getId());
                servicePage.setPageTitle(module.getName());
                servicePage.setQrStyleType(1);
                servicePage.setQrBackgroundColor("");
                servicePage.setQrTextColor("");
                servicePage.setQrTitle(module.getName());
                servicePage.setQrProgramme("");
                servicePage.setDisabled(false);
                adds.add(servicePage);
            }
        }
        long totalPage = totalCount % limit == 0? totalCount / limit : totalCount / limit + 1;
        pageNum++;
        if (pageNum <= totalPage) {
            getModuleServicePage(custAccId, pageNum, totalCount, adds);
        }
    }


    // 获取服务页面列表
    @Override
    public Map<String, Object> getList(Long custAccId, ServicePageSelectVo selectVo) {
        PageUtil.setPageLimit(selectVo);
        List<ServicePageExtend> pageExtends = servicePageService.getList(custAccId, selectVo);

        List<Long> moduleIds = pageExtends.stream().map(ServicePageExtend::getModuleId).filter(f -> 0 != f).toList();
        List<ZjWorkModule> moduleList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(moduleIds)) {
            QueryWrapper<ZjWorkModule> moduleQueryWrapper = new QueryWrapper<>();
            moduleQueryWrapper.select("id", "type");
            moduleQueryWrapper.in("id", moduleIds);
            moduleList.addAll(workModuleService.list(moduleQueryWrapper));
        }

        Map<String, String> paramMap = new HashMap<>();
        List<ServicePageListVo> voList = pageExtends.stream().map(extend -> {
            ServicePageListVo vo = new ServicePageListVo();
            BeanUtil.copyProperties(extend, vo);
            vo.setStatus(extend.getDisabled());
            vo.setTitle(extend.getPageTitle());
            vo.setCreateTime(extend.getGmtCreate());
            vo.setUpdateTime(extend.getGmtUpdate());
            if (extend.getType() == 1 || extend.getType() == 2) {
                String custAccIdAesEncry = BCryptUtil.aesEncry(EnDeSecret.aesKey(), custAccId.toString());
                if (extend.getModuleId() != 0) {
                    try {
                        paramMap.put(UserConstant.CUST_CODE, custAccIdAesEncry);
                        paramMap.put("type", moduleList.stream().filter(f -> Objects.equals(f.getId(), extend.getModuleId())).map(ZjWorkModule::getType).map(String::valueOf).findFirst().orElse(""));
                        paramMap.put(UserConstant.MODULE_CODE, extend.getModuleId().toString());
                        String orderModule = MobilePath.getOrderModule();
                        vo.setPath(TemplateReplaceUtil.template(MobilePath.getOrderModule(), paramMap));
                    } catch (ZbException e) {
                        ZbManager.log.error("字符替换异常：" + e.getMessage());
                    }
                } else {
                 vo.setPath(vo.getPath().replace("{"+ UserConstant.CUST_CODE +"}", custAccIdAesEncry));
                }
            }
            return vo;
        }).toList();
        return PageUtil.pageList(selectVo.getPage(), selectVo.getLimit(), servicePageService.getListCount(custAccId, selectVo), voList);
    }

    // 根据页面ID获取二维码详情
    @Override
    public ServicePageQrDetailVo getServicePageQrDetail(Long id) {
        ZjServicePage page = servicePageService.getById(id);
        Assert.isTrue(null != page, "服务页面ID参数[" + id + "]的页面数据不存在");

        ServicePageQrDetailVo vo = new ServicePageQrDetailVo();
        BeanUtil.copyProperties(page, vo);
        vo.setTitle(page.getPageTitle());
        if (page.getType() == 1 || page.getType() == 2) {
            String custAccIdAesEncry = BCryptUtil.aesEncry(EnDeSecret.aesKey(), page.getCustAccId().toString());
            if (page.getModuleId() != 0) {
                ZjWorkModule module = workModuleService.getById(page.getModuleId());
                vo.setName(module.getName());
                Map<String, String> paramMap = new HashMap<>();
                try {
                    paramMap.put(UserConstant.CUST_CODE, custAccIdAesEncry);
                    paramMap.put("type", module.getType().toString());
                    paramMap.put(UserConstant.MODULE_CODE, module.getId().toString());
                    vo.setPath(TemplateReplaceUtil.template(MobilePath.getOrderModule(), paramMap));
                } catch (ZbException e) {
                    ZbManager.log.error("字符替换异常：" + e.getMessage());
                }
            } else {
                ZjAdmServicePage admServicePage = admServicePageService.getById(page.getAdmServicePageId());
                vo.setName(admServicePage.getName());
                vo.setPath(admServicePage.getPath().replace("{"+ UserConstant.CUST_CODE +"}", custAccIdAesEncry));

            }
        }

        List<ZjServicePageIcon> pageIcons = servicePageIconService.getByServicePageId(id);
        vo.setPageIcons(pageIcons.stream().map(ic -> {
            return new ServicePageIconVo(ic.getId(), ic.getImage(), ic.getSelect());
        }).toList());
        return vo;
    }

    // 根据页面ID获取页面标题详情
    @Override
    public ServicePageTitleDetailVo ServicePageTitleDetail(Long id) {
        ZjServicePage page = servicePageService.getById(id);
        Assert.isTrue(null != page, "服务页面ID参数[" + id + "]的页面数据不存在");

        ServicePageTitleDetailVo vo = new ServicePageTitleDetailVo();
        BeanUtil.copyProperties(page, vo);
        vo.setTitle(page.getPageTitle());
        vo.setStatus(page.getDisabled());
        if (page.getType() == 1 || page.getType() == 2) {
            if (page.getModuleId() != 0) {
                ZjWorkModule module = workModuleService.getById(page.getModuleId());
                vo.setName(module.getName());
                Map<String, String> paramMap = new HashMap<>();
                try {
                    paramMap.put(UserConstant.CUST_CODE, BCryptUtil.aesEncry(EnDeSecret.aesKey(), page.getCustAccId().toString()));
                    paramMap.put("type", module.getType().toString());
                    paramMap.put(UserConstant.MODULE_CODE, module.getId().toString());
                    vo.setPath(TemplateReplaceUtil.template(MobilePath.getOrderModule(), paramMap));
                } catch (ZbException e) {
                    ZbManager.log.error("字符替换异常：" + e.getMessage());
                }
            } else {
                ZjAdmServicePage admServicePage = admServicePageService.getById(page.getAdmServicePageId());
                vo.setName(admServicePage.getName());
                vo.setPath(admServicePage.getPath());
            }
        }
        return vo;
    }
}
